Unity 加载资源与存储数据
DontDestroyOnLoad
参考资料 Unity中DontDestroyOnLoad在切换场景时的坑点
DontDestroyOnLoad 可以保证 Gameobject 以及上面绑定的组件不会销毁,在处理全局控制的时候有用。
public class ExampleClass :MonoBehaviour{
void Awake() {
DontDestroyOnLoad(gameObject);
}
}
运行时就会把这个对象丢到 DontDestroyOnLoad 这里
但是要注意使用 DontDestroyOnLoad 的时候需要注意的坑:
由于使用 DontDestroyOnLoad 的物体不会被释放掉,假设我们写了上面的代码,而物体所在的游戏场景又可以重复进入的时候,游戏物体就会在每次进入场景的时候创建一次,甚至可以无限创建下去,这样的处理明显不妥。
针对性的解决方案:(注意不可以在 Unity 里面使用静态构造方法的方式实例对象)
判断一下引用是否为空,如果为空再设置为 DontDestroyOnLoad,如果不为空则删除此游戏物体
public class GameManager : MonoBehaviour
{
public static GameManager Instance { get; set; }//单例
private void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
}
else
{
Instance = this;
DontDestroyOnLoad(this);
}
}
}
Unity 加载资源
参考资料 unity3d Resources.Load动态加载资源
Unity3d 常用两种加载资源方案:Resources.Load
和 AssetBundle
Resources.Load 加载资源
官方文档使用 Resources.Load
使用这种方式加载资源,首先需要下 Asset 目录下创建一个名为 Resources 的文件夹,这个命名是 Unity 规定的方式,然后把资源文件放进去,
当然也可以在 Resources 中再创建子文件夹,当然在代码加载时需要添加相应的资源路径
using UnityEngine;
using System.Collections;
public class LoadResDemo : MonoBehaviour {
// 这里的根路径就是 Resources 目录
private string cubePath = "Prebs/MyCubePreb"; // Asset/Resources/Prebs/MyCubePreb
private string spherePath = "MySpherePreb"; // Asset/Resources/MySpherePreb
void Start () {
//把资源加载到内存中
Object cubePreb = Resources.Load(cubePath, typeof(GameObject));
//用加载得到的资源对象,实例化游戏对象,实现游戏物体的动态加载
GameObject cube = Instantiate(cubePreb) as GameObject;
//以下同理实现Sphere的动态实例化
//把资源加载到内存中
Object spherePreb = Resources.Load(spherePath, typeof(GameObject));
//用加载得到的资源对象,实例化游戏对象,实现游戏物体的动态加载
GameObject sphere = Instantiate(spherePreb) as GameObject;
}
void Update () {
}
}
注意!! Resources.Load
加载资源不用加文件后缀
// 加载 Assets/Resources/TileSprite/TileSpriteAtlas.asset
// 不用加文件后缀
SpriteLibraryAsset sa = Resources.Load<SpriteLibraryAsset>("TileSprite/TileSpriteAtlas");
加载 JSON 文件
public string JsonRead(string name)
{
string json = "";
TextAsset text = Resources.Load<TextAsset>("Jsons/" + name);
json = text.text;
if (string.IsNullOrEmpty(json)) return null;
return json;
}
获取文件路径
一般存档之类的文件丢到这个 Application.persistentDataPath
目录里面来
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class GameSaveManager : MonoBehaviour
{
public Inventory myInventory;
void Awake()
{
SaveGame();
}
public void SaveGame()
{
Debug.Log(Application.persistentDataPath);
// 如果不存在则创建目录
if (!Directory.Exists(Application.persistentDataPath + "/game_SaveData"))
{
Directory.CreateDirectory(Application.persistentDataPath + "/game_SaveData");
}
}
}
创建资源路径
AssetDatabase.GetAssetPath
获取资源路径
@MenuItem("GameObject/Create Material")
static function CreateMaterial () {
//新建一个简单的材质资源
var material = new Material (Shader.Find("Specular"));
// 创建一个资源到 Assets 目录下面
AssetDatabase.CreateAsset(material, "Assets/MyMaterial.mat");
//打印新建资源的路径
Debug.Log(AssetDatabase.GetAssetPath(material));
}
Unity 场景管理
参考资料 Unity 通用场景管理器分享 参考资料 【Unity】场景管理/切换:SceneManager、GetScene、LoadScene、MoveGameObjectToScene等
首先别忘了把当前场景添加到 Build Settings 里面
重新加载场景
GetActiveScene 是取得当前已经激活的场景
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
ScriptableObject 保存数据
参考资料 ScriptableObject
ScriptableObject 是一个可独立于类实例来保存大量数据的数据容器。ScriptableObjects 的一个主要用例是通过避免重复值来减少项目的内存使用量。如果项目有一个预制件在附加的 MonoBehaviour 脚本中存储不变的数据,这将非常有用。
每次实例化预制件时,都会产生单独的数据副本。这种情况下可以不使用该方法并且不存储重复数据,而是使用 ScriptableObject 来存储数据,然后通过所有预制件的引用访问数据。这意味着内存中只有一个数据副本。
// 即,继承的不是 MonoBehaviour 而是 ScriptableObject
// 这个 fileName 是创建的资源默认名字
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/New Item", order = 1)]
public class Item : ScriptableObject // 继承的不是 MonoBehaviour
{
...
}
与 MonoBehaviour 类似,ScriptableObjects 派生自 Unity 基对象,但不同于 MonoBehaviour 之处在于,不能将 ScriptableObject 附加到 GameObject。而是应该将它们保存为项目中的资源。
ScriptableObjects 的主要用例为:
- 在 Editor 会话期间保存和存储数据
- 将数据保存为项目中的资源,以便在运行时使用
要使用 ScriptableObject,创建一个脚本,并使其继承自 ScriptableObject 类(然后无需让它挂载在任何的空物体上)。可以使用 CreateAssetMenu 属性,从而使用这个的类轻松创建自定义资源。例如:
[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/New Item")]
public class Item : ScriptableObject
{
public string itemName;
public Sprite itemImage; //渲染的精灵
public int itemHeld; //当前Item的数量
[TextArea] // 如果当描述信息很多的时候可以用这个属性,让它变成一个文本框(它还有其它的属性,最大行数,最小行数)
public string itemInfo;
public bool equip; // 当前物品是否可装备
}
然后在资源菜单就可以看到这个创建资源的选项
这个创建的资源如下所示:
使用 LitJson 处理 JSON 数据
首先到官网下载这个 dll 文件(可以使用其它的 JSON 工具)
下载 地址(默认浏览器会拦截 dll 文件,下载后注意是否被拦截了)
将下载的 dll 文件拖拽到 Unity的 Plugins 文件夹下面(自己创建)
JSON 文件如下
{
"age" : [1,2,3,4],
"map" : [[1,2,3],[4,5,6]]
}
使用方法
//获取Json中的文本。文本在unity中是 TextAsset 类型,文件无需加后缀
TextAsset jsonText = Resources.Load<TextAsset>("Jsons/mapData");
//把json文本转换为 jsonData格式
JsonData itemData = JsonMapper.ToObject(jsonText.text);
int[] ages = (int[])itemData["age"] // [1,2,3,4]
int a = itemData["map"][1][2] // 6